; pvz.: 0000:02E0: 050100      add ax,1             ; ax = 0010h

LOCALS @@                           ; Lokalios zymes prasideda @@

.MODEL small                        ; 64K kodui ir 64K duomenims

.STACK 100h

.DATA

komanda   db 14 DUP(?)
mnemonika db 'add '
          db 22 DUP(?)
adresas   db 11 DUP(?)
operandai db 30 DUP(?)
registrai db 'ALAXCLCXDLDXBLBXAHSPCHBPDHSIBHDI'
adresai   db 'BX+SI   BX+DI   BP+SI   BP+DI   SIDIBPBX'
poslinkis db 4 DUP(?)

.CODE 

OldISRSeg DW 0
OldISROfs DW 0
W         db 0
D         db 0
modas     db 0
reg       db 0
rm        db 0
var       db 0
registru_reiksmes db 16

Strt:
  mov ax,@data
  mov ds,ax
  
  mov ax, 0
  mov es, ax

  ; --- Issaugome senos pertraukimo apdorojimo proceduros adresa
  push    ds                      ; Isaugoti ds
  mov     ax, 3501h               ; AH=25h, AL=0FFh
  int 21h
  mov     ax, ds                  ; Pakrauti  DS:DX
  mov     [OldISRSeg], ax         ; procedros adres
  mov     [OldISROfs], dx 
  pop     ds                      ; Atstatyti DS
  
  ; --- "Instaliuojame" nauja pertraukimu apdorojimo procedura
  
  push    ds                      ; Isaugoti ds
  mov     ax, 2501h               ; AH=25h, AL=0FFh
  mov     dx, seg Zingsnis        ; Pakrauti  DS:DX
  mov     ds, dx                  ; procedros adres
  mov     dx, offset Zingsnis
  int     21h                     ; Ikviesti DOS funkcij
  pop     ds                      ; Atstatyti DS
  
  cld

  ; --- bandom
  ; --- Ijungti TF
  pushf
  pop ax
  xor ax, 0100h
  push ax
  popf
  
  ; --- viskas ok, po sekanchiu komandu bus zingsniavimo interruptas
  
  sub dx, cx
  xor bx, bx
  push ss
  pop ss
  add ax,ax
  add bx,bx
  add [komanda+bx+si], 1
  
  ; --- po shiu zhingsniu nebebus jau interruptu  ---------
  
  
  ; --- isjungiame trap flaga
  pushf
  pop ax
  xor ax, 0100h
  push ax
  popf

  ; --- Atstatome sena pertraukimu apdorojimo procedura
  push    ds                      ; Isaugoti ds
  mov     ax, 2501h               ; AH=25h, AL=0FFh
  mov     dx, [OldISRSeg]         ; Pakrauti  DS:DX
  mov     ds, dx                  ; procedros adres
  mov     dx, [OldISROfs]
  int     21h                     ; Ikviesti DOS funkcij
  pop     ds                      ; Atstatyti DS

  ; --- Baigiame darba
  mov ax,04C00h
  int 21h                 ; int 21,4C - programos pabaiga 
  
  ; --- Proceduros
  
  Zingsnis PROC
    ; d - krypties bitas (is proc i reg. kai = 0)
    ; w - kai 0 - operandas baitas, 1 - zodis
    ; mod 00 - operandas atmintyje (r/m = m), poslinkio nera
    ;     01 - operandas atmintyje, vieno baito poslinkis
    ;     10 - operandas atmintyje, dvieju baitu poslinkis
    ;     11 - operandas registre (r/m - r)
    
    ; add: 1. reg + reg/atm.: 0000 00dw mod reg r/m [poslinkis]
    ;      2. reg/atm. + bet.op.:
    ;            1000 00sw mod 000 r/m [poslinkis] bet.op.j.b [bet.op.v.b]
    ;      3. akumuliatorius + betarp.op.
    ;            0000 010w bet.op.j.b [bet.op.v.b jei w=1]
    
    ; pasiimame is stacko viska ka reikia :)
    
    
    ; --- turime stacke cs ir ip :) pasiimam juos 
    mov word ptr [registru_reiksmes], ax
    mov word ptr [registru_reiksmes+2], cx
    mov word ptr [registru_reiksmes+4], dx
    mov word ptr [registru_reiksmes+6], bx
    mov word ptr [registru_reiksmes+8], sp
    mov word ptr [registru_reiksmes+10], bp
    mov word ptr [registru_reiksmes+12], si
    mov word ptr [registru_reiksmes+14], di
    
    mov dx, ds
    mov es, dx
    pop si
    pop ds
    push ds
    push si
    ; --- galime nueiti adresu ds:si ir pasiziureti kas ten yra gero :)
    lodsb ; uzloadiname pirmaji baita tuo adresu
    
    cmp al, 0
    jl @@toliau
    cmp al, 3
    jg @@toliau
    ; reg + reg/atm
    ; 0000 00dw mod reg r/m [poslinkis]
    mov [var], 1 
    
    jmp @@toliau3
    
    @@toliau:
    cmp al, 128
    jl @@toliau2
    cmp al, 131
    jg @@toliau2
    ; reg/atm + bet.op.
    ; patikrinam ar tikrai add, o ne adc
    
    mov cx, ax 
    xor ah, ah
    
    lodsb
    mov bx, 1000b
    div bl
    xor ah, ah
    div bl
    
    cmp ah, 0
    jne @@Exit
    
    dec si
    mov ax, cx
    
    mov [var], 2
    
    jmp @@toliau3
    
    @@toliau2:
    cmp al, 4
    jl @@Exit
    cmp al, 5
    jg @@Exit
    ; acc + bet.op.
    mov [var], 3
    
    @@toliau3:
    
    call Laukai
    call Imu_operandus
    call Imu_adresa
    call Imu_komanda
    call Imu_mnemonika

    push ds
    mov dx, es
    mov ds, dx
    
    mov cx, 11
    mov dx, offset adresas
    call PrintBuf
    
    mov cx, 14
    mov dx, offset komanda
    call PrintBuf
    
    mov cx, 22
    mov dx, offset mnemonika
    call PrintBuf
    
    mov cx, 30
    mov dx, offset operandai
    call PrintBuf 
    
    xor bx, bx
    mov cx, 14
    @@valom:
    mov [komanda+bx], ' '
    inc bx
    loop @@valom 
    
    mov bx, 4
    mov cx, 19
    @@valom2:
    mov [mnemonika+bx], ' '
    inc bx
    loop @@valom2 
    
    xor bx, bx
    mov cx, 30
    @@valom3:
    mov [operandai+bx], ' '
    inc bx
    loop @@valom3 

    pop ds
    
    @@Exit:
    mov dx, es
    mov ds, dx
    iret
    
  Zingsnis ENDP 
  
  ; al turime pirma baita, ds:si rodo i komandos antra baita
  ; nustatome komanda
  
  ; al turime baita (reikalinga)
  Sesioliktainis PROC
    push ax
    xor ah, ah
    mov cl, 10h
    div cl
    ; sveikaja dali turim al, liekana - ah
    cmp al, 9
    ja @@raides
    add al, 48
    jmp @@toliau
    @@raides:
    add al, 55

    @@toliau:
    cmp ah, 9
    ja @@raides2
    add ah, 48
    jmp @@Exit
    @@raides2:
    add ah, 55
    
    @@Exit:
    ; apkeiciam vietom
    mov cl, ah
    mov ch, al
    ; popinam
    pop ax
    ret    
  Sesioliktainis ENDP
  
  Laukai PROC
    ; nustatom d ir w kintamuosius :)
    push ax
    push bx 
    push si
    
    dec si    
    lodsb
    ; al turime komanda :)
    
    xor ah, ah
    mov bx, 10b
    div bl
    ; al - sveik. ah - liek.
    mov [W], ah
    xor ah, ah
    div bl
    mov [D], ah
    
    lodsb
    ; ax turime 2 baita OPK
    mov bx, 1000b
    div bl
    ; ah - liek (r/m), al - sveikoji (mod ir reg)
    mov [rm], ah
    
    xor ah, ah
    div bl
    ; ah - liek (reg), al - sveikoji (mod)
    mov [reg], ah
    
    xor ah, ah
    mov bx, 100b
    div bl
    mov [modas], ah
    
    pop si
    pop bx
    pop ax
    ret
  Laukai ENDP
  
  Imu_operandus PROC
    push ax
    push bx
    push cx
    push dx
    
    mov di, 0
    mov bx, 1 
    cmp [var], 3
    jne @@toliau
      cmp [W], 1
      je @@word
        ; jeigu ne zodis, tai baitas:) baita atprintinti turim reiksmes
        ; issaugotas atmintyje :)
        push ds
        mov dx, es
        mov ds, dx
        mov word ptr [operandai+di], 'LA'
        add di, 2
        mov [operandai+2], '='
        inc di
        pop ds
        mov cx, 1
        inc bx
        jmp @@sokam
      @@word:
        push ds
        mov dx, es
        mov ds, dx
        mov word ptr [operandai+di], 'XA'
        add di, 2
        mov [operandai+di], '='
        inc di
        pop ds
        mov cx, 2
      @@sokam:
        cmp cx, 1 
        jne @@varom  ; apkeiciam baitus vietom, jei reikia :)
          sub bx, 2
        @@varom:
        push cx
        mov al, [registru_reiksmes+bx]
        push ds
        mov dx, es
        mov ds, dx
        call Sesioliktainis
        mov [operandai+di], ch
        inc di
        mov [operandai+di], cl
        inc di
        pop ds
        inc bx 
        pop cx
        loop @@sokam
        push ds
        mov dx, es
        mov ds, dx
        mov [operandai+di], 'h'
        inc di
        pop ds
    @@toliau:
    
    cmp [var], 2
    jne @@toliau2
      cmp [modas], 11b
      jne @@mem
        
        mov bl, [rm]
        xor bh, bh
        call Operando_reiksme
        jmp @@Exit
               
      @@mem:
      
        call Atminties_oper
        jmp @@Exit
    
    @@toliau2:
    ; lieka tik pirmas variantas :) taigi
    ; pirmiausia spauzdiname registra
      mov bl, [reg]
      xor bh, bh
      call Operando_reiksme
      
    ; toliau - atminti arba registra :)
      cmp [modas], 11b
      jne @@mem2
        mov bl, [rm]
        xor bh, bh
        call Operando_reiksme
        jmp @@Exit
        
      @@mem2:
      
        call Atminties_oper
            
    @@Exit: 
    
    pop dx
    pop cx
    pop bx
    pop ax
    ret
    
  Imu_operandus ENDP
  
  Atminties_oper PROC
    push ax
    push bx
    push cx
    push dx
    
    cmp [rm], 001b
    jle @@gerai
      jmp @@trys
    @@gerai:
    ; BX+SI
      push ds
      mov dx, es
      mov ds, dx    
      mov word ptr [operandai+di], 'XB'
      add di, 2
      mov [operandai+di], '='
      inc di
      pop ds
      
      mov bx, 6 ; nes bx yra 3 :)
      
      mov cx, 2 
      inc bx
      @@ciklas:
      cmp cx, 1
      jne @@varom
        sub bx, 2
      @@varom:
      push cx
      mov al, [registru_reiksmes+bx]
      inc bx
      push ds
      mov dx, es
      mov ds, dx
      call Sesioliktainis
      mov [operandai+di], ch
      inc di
      mov [operandai+di], cl
      inc di
      pop ds
      pop cx
      loop @@ciklas
      push ds
      mov dx, es
      mov ds, dx
      mov word ptr [operandai+di], ' h'
      add di, 2
      pop ds
      
      cmp [rm], 000b
      jne @@toliau      
      
      push ds
      mov dx, es
      mov ds, dx
      mov word ptr [operandai+di], 'IS'
      add di, 2
      mov [operandai+di], '='
      inc di
      pop ds
      
      mov bx, 1100b ; nes si yra 110b
      
      jmp @@sokam
      
      @@toliau: 
      push ds
      mov dx, es
      mov ds, dx
      mov word ptr [operandai+di], 'ID'
      add di, 2
      mov [operandai+di], '='
      inc di
      pop ds
      
      mov bx, 1110b ; nes di yra toks :)
      
      @@sokam:
      
      mov cx, 2 
      inc bx
      @@ciklas2:
      cmp cx, 1
      jne @@varom2
        sub bx, 2
      @@varom2:
      push cx
      mov al, [registru_reiksmes+bx]
      inc bx
      push ds
      mov dx, es
      mov ds, dx
      call Sesioliktainis
      mov [operandai+di], ch
      inc di
      mov [operandai+di], cl
      inc di
      pop ds
      pop cx
      loop @@ciklas2
      push ds
      mov dx, es
      mov ds, dx
      mov word ptr [operandai+di], ' h'
      add di, 2
      pop ds
      
      jmp @@Exit

    @@trys:
    cmp [rm], 011b
    jle @@gerai2
      jmp @@penki
    @@gerai2:

      push ds
      mov dx, es
      mov ds, dx    
      mov word ptr [operandai+di], 'PB'
      add di, 2
      mov [operandai+di], '='
      inc di
      pop ds
      
      mov bx, 1010b ; nes bp yra 101 :)
                 
      mov cx, 2 
      inc bx
      @@ciklas3:
      cmp cx, 1
      jne @@varom3
        sub bx, 2
      @@varom3:
      push cx
      mov al, [registru_reiksmes+bx]
      inc bx
      push ds
      mov dx, es
      mov ds, dx
      call Sesioliktainis
      mov [operandai+di], ch
      inc di
      mov [operandai+di], cl
      inc di
      pop ds
      pop cx
      loop @@ciklas3
      push ds
      mov dx, es
      mov ds, dx
      mov word ptr [operandai+di], ' h'
      add di, 2
      pop ds
      
      cmp [rm], 010b
      jne @@toliau2
      
      push ds
      mov dx, es
      mov ds, dx      
      mov word ptr [operandai+di], 'IS'
      add di, 2
      mov [operandai+di], '='
      inc di
      pop ds
      
      mov bx, 1100b ; nes si yra 110b
      
      jmp @@sokam2
      
      @@toliau2:
       
      push ds
      mov dx, es
      mov ds, dx
      mov word ptr [operandai+di], 'ID'
      add di, 2
      mov [operandai+di], '='
      inc di
      pop ds
      
      mov bx, 1110b ; nes di yra toks :)
      
      @@sokam2:
      
      mov cx, 2 
      inc bx
      @@ciklas4:
      cmp cx, 1
      jne @@varom4
        sub bx, 2
      @@varom4:
      push cx
      mov al, [registru_reiksmes+bx]
      inc bx
      push ds
      mov dx, es
      mov ds, dx
      call Sesioliktainis
      mov [operandai+di], ch
      inc di
      mov [operandai+di], cl
      inc di
      pop ds
      pop cx
      loop @@ciklas4
      push ds
      mov dx, es
      mov ds, dx
      mov word ptr [operandai+di], ' h'
      add di, 2
      pop ds 
      
      jmp @@Exit
    
    @@penki:
    cmp [rm], 100b
    jne @@sesi
      push ds
      mov dx, es
      mov ds, dx    
      mov word ptr [operandai+di], 'IS'
      add di, 2
      mov [operandai+di], '='
      inc di
      pop ds
      mov bx, 1100b ; nes si yra 110b
      mov cx, 2 
      inc bx
      @@ciklas5:
      cmp cx, 1
      jne @@varom5
        sub bx, 2
      @@varom5:
      push cx
      mov al, [registru_reiksmes+bx]
      inc bx
      push ds
      mov dx, es
      mov ds, dx
      call Sesioliktainis
      mov [operandai+di], ch
      inc di
      mov [operandai+di], cl
      inc di
      pop ds
      pop cx
      loop @@ciklas5
      push ds
      mov dx, es
      mov ds, dx
      mov word ptr [operandai+di], ' h'
      add di, 2
      pop ds
      
      jmp @@Exit
    
    @@sesi:
    cmp [rm], 101b
    jne @@septyni
      push ds
      mov dx, es
      mov ds, dx    
      mov word ptr [operandai+di], 'ID'
      add di, 2
      mov [operandai+di], '='
      inc di 
      pop ds
      mov bx, 1110b ; nes di yra 111b
      mov cx, 2 
      inc bx
      @@ciklas6:
      cmp cx, 1
      jne @@varom6
        sub bx, 2
      @@varom6:
      push cx
      mov al, [registru_reiksmes+bx]
      inc bx
      push ds
      mov dx, es
      mov ds, dx
      call Sesioliktainis
      mov [operandai+di], ch
      inc di
      mov [operandai+di], cl
      inc di
      pop ds
      pop cx
      loop @@ciklas6
      push ds
      mov dx, es
      mov ds, dx
      mov word ptr [operandai+di], ' h'
      add di, 2
      pop ds
    
      jmp @@Exit
    
    @@septyni:
    cmp [rm], 110b
    jne @@astuoni
    ; siuo atveju printins tik tada kai bus poslinkis, taigi
    cmp [modas], 00
    je @@gerai3
      jmp @@Exit
    @@gerai3:
      push ds
      mov dx, es
      mov ds, dx    
      mov word ptr [operandai+di], 'PB'
      add di, 2
      mov [operandai+di], '='
      inc di  
      pop ds
      mov bx, 1010b ; nes bp yra 1010b
      mov cx, 2 
      inc bx
      @@ciklas7:
      cmp cx, 1
      jne @@varom7
        sub bx, 2
      @@varom7:
      push cx
      mov al, [registru_reiksmes+bx]
      inc bx
      push ds
      mov dx, es
      mov ds, dx
      call Sesioliktainis
      mov [operandai+di], ch
      inc di
      mov [operandai+di], cl
      inc di
      pop ds
      pop cx
      loop @@ciklas7
      push ds
      mov dx, es
      mov ds, dx
      mov word ptr [operandai+di], ' h'
      add di, 2
      pop ds
      
      jmp @@Exit
    
    @@astuoni:
    cmp [rm], 111b
    jne @@Exit
      push ds
      mov dx, es
      mov ds, dx
      mov word ptr [operandai+di], 'XB'
      add di, 2
      mov [operandai+di], '='
      inc di                  
      pop ds
      mov bx, 6 ; nes bx yra 3
      mov cx, 2 
      inc bx
      @@ciklas8:
      cmp cx, 1
      jne @@varom8
        sub bx, 2
      @@varom8:
      push cx
      mov al, [registru_reiksmes+bx]
      inc bx
      push ds
      mov dx, es
      mov ds, dx
      call Sesioliktainis
      mov [operandai+di], ch
      inc di
      mov [operandai+di], cl
      inc di
      pop ds
      pop cx
      loop @@ciklas8
      push ds
      mov dx, es
      mov ds, dx
      mov word ptr [operandai+di], ' h'
      add di, 2
      pop ds
    
    @@Exit:
    
    pop dx
    pop cx
    pop bx
    pop ax 
    ret   
  Atminties_oper ENDP
  
  Operando_reiksme PROC ; di rodo ten, turi but irasyta atstumu tuo [operandai] pradzios..:)
    ; bx - r/m arba reg reiksme:)
    push bx
    push cx
    push ax
    push dx
    
    push bx    
    shl bx, 2

    cmp [W], 0
    je @@byte ; jeigu W = 0, tai tada baitas :)
    ; kitu atveju, prie bx pridedam 2 :)
      add bx, 2
      inc cx
    @@byte:
    push ds
    
    mov dx, es
    mov ds, dx
    mov al, [registrai+bx]
    mov [operandai+di], al
    inc di
    inc bx
    mov al, [registrai+bx]
    mov [operandai+di], al
    inc di
    inc bx
    mov [operandai+di], '='
    inc di
    
    pop ds
    
    ; atprintinam registro pavadinima ir = :)
    
    pop bx
    shl bx, 1
    cmp [W], 1
    je @@word
      cmp bx, 100b
      jl @@varom
        ; jeigu vyresnysis, tai tada atliekam tam tikrus veiksmus, kad ishtraukti ji ish atminties      
        sub bx, 1000b
        inc bx
      @@varom:
      push cx
      mov al, [registru_reiksmes+bx]
      inc bx
      push ds
      mov dx, es
      mov ds, dx
      call Sesioliktainis
      mov [operandai+di], ch
      inc di
      mov [operandai+di], cl
      inc di
      mov word ptr [operandai+di], ' h'
      add di, 2
      pop ds
      pop cx
      jmp @@Exit
    @@word:
      mov cx, 2 
      inc bx
      @@ciklas:
      cmp cx, 1
      jne @@varom2
        sub bx, 2
      @@varom2:
      push cx
      mov al, [registru_reiksmes+bx]
      inc bx
      push ds
      mov dx, es
      mov ds, dx
      call Sesioliktainis
      mov [operandai+di], ch
      inc di
      mov [operandai+di], cl
      inc di
      pop ds
      pop cx
      loop @@ciklas
      push ds
      mov dx, es
      mov ds, dx
      mov word ptr [operandai+di], ' h'
      add di, 2
      pop ds
    @@Exit:
    pop dx
    pop cx
    pop bx
    pop ax
    ret
    
  Operando_reiksme ENDP
  
  
  Imu_adresa PROC
    ; turim ds'e segmento adresa, o si-1  - offseta  
    push si
    push ax
    push bx
    
    push ds
    mov dx, es
    mov ds, dx
    
    mov bx, ds
    mov al, bh
    xor ah, ah
    
    call Sesioliktainis
    mov [adresas+0], ch
    mov [adresas+1], cl
    
    mov al, bl
    call Sesioliktainis
    mov [adresas+2], ch
    mov [adresas+3], cl
    
    mov [adresas+4], ':'
    
    dec si    
    mov bx, si
    mov al, bh
    xor ah, ah
    
    call Sesioliktainis
    mov [adresas+5], ch
    mov [adresas+6], cl
    
    mov al, bl
    call Sesioliktainis
    mov [adresas+7], ch
    mov [adresas+8], cl
    
    mov [adresas+9], ':'
    
    pop ds
    
    pop bx
    pop ax
    pop si
    
    ret
  Imu_adresa ENDP
  
  Imu_komanda PROC
    push ax
    push bx
    push dx
    push cx
    push si
    
    dec si
    lodsb
    xor ah, ah
    
    
    call Sesioliktainis
    push ds
    mov dx, es
    mov ds, dx
    mov [komanda+0], ch
    mov [komanda+1], cl 
    pop ds
    ; turiu pirmoji dalis komandos (pirmas baitas)
    ; pasiimu antra dali
    
    ; jeigu 3 var (acc+bet.op) ir w=1, tai reikia nuskaityti dar du baitus :)
    cmp [var], 3
    je @@betarp_op
        
    lodsb
    
    call Sesioliktainis
    push ds
    mov dx, es
    mov ds, dx
    mov [komanda+2], ch
    mov [komanda+3], cl
    pop ds       
    
    mov bx, 4
    mov di, 0
    
    cmp [modas], 10b
    je @@2baitu_pos
    cmp [modas], 01b
    je @@baito_pos
    cmp [modas], 11b
    je @@betarp_op
    
    ; lieka tiktai mod = 00b, jei nei vienas is situ :)
    ; palyginam r/m, nes jei r/m = 110, tai dar  - ties. 2baitu adresas :)
    
    cmp [rm], 110b
    jne @@Exit
    
    @@2baitu_pos:
    lodsb        
    push ds
    mov dx, es
    mov ds, dx
    call Sesioliktainis    
    mov [komanda+bx], ch
    mov [poslinkis+di], ch
    inc bx              
    inc di
    mov [komanda+bx], cl
    mov [poslinkis+di], cl
    inc di
    inc bx
    pop ds
    
    @@baito_pos:
    lodsb
    push ds
    mov dx, es
    mov ds, dx
    call Sesioliktainis 
    mov [komanda+bx], ch
    mov [poslinkis+di], ch
    inc bx              
    inc di
    mov [komanda+bx], cl
    mov [poslinkis+di], cl
    inc di
    inc bx
    pop ds
    
    cmp [var], 2
    jne @@Exit
        
    @@betarp_op:
    call bet_op
    
    @@Exit:
    pop si
    pop cx
    pop dx
    pop bx
    pop ax
    
    ret    
  Imu_komanda ENDP
  
  Imu_mnemonika PROC
    push ax
    push bx
    push dx
    push cx
    
    cmp [var], 1
    jne @@antras
    ; pirmas variantas (reg + reg/atm)
    call Pirmas
    jmp @@Exit

    @@antras:
    cmp [var], 2
    jne @@trecias
    call Antras
    jmp @@Exit
    
    @@trecias:
    cmp [var], 3
    jne @@Exit
    call Trecias     
    
    @@Exit:    
    pop cx
    pop dx
    pop bx
    pop ax
    ret
  Imu_mnemonika ENDP 
  
  Pirmas PROC
    push bx
    push ax
    push cx
    
    mov di, 4

    cmp [D], 1 ; jeigu D bitas - 1, tai tada reg/atm + reg :) jeigu 0, tai atv.
    jne @@reverse_direction ; jei normali kryptis, nuskaitom registra
    
    mov bl, [reg]
    xor bh, bh
    shl bx, 2
    cmp [W], 0
    je @@byte ; jeigu W = 0, tai tada baitas :)
    ; kitu atveju, prie bx pridedam 2 :)
    add bx, 2
    @@byte:
    push ds
    
    mov dx, es
    mov ds, dx
    mov al, [registrai+bx]
    mov [mnemonika+di], al
    inc di
    inc bx
    mov al, [registrai+bx]
    mov [mnemonika+di], al
    inc di
    inc bx
    
    ; padedam kableli :)    
    mov [mnemonika+di], ','
    inc di
    
    pop ds
    
    call reg_or_mem ; likusi darba padaro procedura :)
    
    jmp @@Exit
    
    @@reverse_direction:
    
    call reg_or_mem
    
    push ds
    mov dx, es
    mov ds, dx
    mov [mnemonika+di], ','
    inc di
    pop ds
    
    mov bl, [reg]
    xor bh, bh
    shl bx, 2
    cmp [W], 0
    je @@byte1 ; jeigu W = 0, tai tada baitas :)
    ; kitu atveju, prie bx pridedam 2 :)
    add bx, 2
    @@byte1:
    push ds
    
    mov dx, es
    mov ds, dx
    mov al, [registrai+bx]
    mov [mnemonika+di], al
    inc di
    inc bx
    mov al, [registrai+bx]
    mov [mnemonika+di], al
    inc di
    inc bx
    
    pop ds
        
    @@Exit:
    
    pop cx
    pop ax
    pop bx
    ret
  Pirmas ENDP
  
  Antras PROC
    push ax
    push bx
    push cx
    push dx
    
    ; reg/atm + bet.op.
    
    mov di, 4
    call reg_or_mem
    ; pasiimame registra [atminty]
    ; di rodo i ten kur spaustinti sekanti :)
    
    push ds
    mov dx, es
    mov ds, dx
    mov [mnemonika+di], ','
    inc di
    pop ds
    
    cmp [modas], 11b ; jeigu modas = 11, tai irgi jokio posl.
    jne @@ne
    xor dl, dl
    jmp @@sokam2
    @@ne:
    mov dl, [modas]
    @@sokam2:
    xor dh, dh
    shl dx, 1
    add dx, 4
    mov bx, dx
    ; dx - kur yra bet.op. pradzia komandoje :)
    
    ; dar, jeigu mod = 00, o r/m 110, tuomet yra tiesiog. adresas :)
    cmp [modas], 00
    jne @@sokam
    cmp [rm], 110b
    jne @@sokam
    
    add bx, 4
    
    @@sokam:
        
    cmp [W], 1
    jne @@baitas
    
    cmp [D], 0 ; siuo atveju D bitas yra S :) tiesiog nesinori keist
    ; taigi, jeigu s:w = 01, tuomet operantas 2 baitu imamas is komandos
    jne @@baitas ; jeigu 00, tai tada operandas imamas is 8 bitu ir ispleciamas iki 16

    add bx, 2
    mov cx, 4
    
    ; vel reikia apkeisti nes j.b.o.b. yra pirmiau nei vyr.
    
    push ds
    mov ax, es
    mov ds, ax
    
    @@ciklas:
      cmp cx, 2 ; po 2 baitu shokam i prieki :) (jaun.bet.o.b)
      jne @@sokam1
        sub bx, 4
      @@sokam1:
      mov al, [komanda+bx]
      mov [mnemonika+di], al
      inc di
      inc bx
    loop @@ciklas
    mov [mnemonika+di], 'h'
    inc di
    
    pop ds
    
    jmp @@Exit
    
    @@baitas:
    mov cx, 2
    
    ; vel reikia apkeisti nes j.b.o.b. yra pirmiau nei vyr.
    
    push ds
    mov ax, es
    mov ds, ax
    
    @@ciklas2:
      mov al, [komanda+bx]
      mov [mnemonika+di], al
      inc di
      inc bx
    loop @@ciklas2
    mov [mnemonika+di], 'h'
    inc di
    
    pop ds    
    
    @@Exit:
    pop dx
    pop cx
    pop bx
    pop ax
    ret
    
  Antras ENDP
  
  Trecias PROC
    
    push ax
    push bx
    push cx
    push dx
    
    mov di, 4
    mov bx, 2
    
    cmp [W], 1
    jne @@baitas

    add bx, 2    
    mov cx, 4
    
    ; vel reikia apkeisti nes j.b.o.b. yra pirmiau nei vyr.
    
    push ds
    mov ax, es
    mov ds, ax

    
    mov word ptr [mnemonika+di], 'XA'
    add di, 2
    mov [mnemonika+di], ','
    inc di
    
    @@ciklas:
      cmp cx, 2 ; po 2 baitu shokam i prieki :) (jaun.bet.o.b)
      jne @@sokam1
        sub bx, 4
      @@sokam1:
      mov al, [komanda+bx]
      mov [mnemonika+di], al
      inc di
      inc bx
    loop @@ciklas
    mov [mnemonika+di], 'h'
    inc di
    
    pop ds
    
    jmp @@Exit
    
    @@baitas:
    
    mov cx, 2
    
    push ds
    mov ax, es
    mov ds, ax
    
    mov word ptr [mnemonika+di], 'LA'
    add di, 2
    mov [mnemonika+di], ','
    inc di
    
    @@ciklas2:
      mov al, [komanda+bx]
      mov [mnemonika+di], al
      inc di
      inc bx
    loop @@ciklas2
    mov [mnemonika+di], 'h'
    inc di
    
    pop ds
    
    @@Exit:
    pop dx
    pop cx
    pop bx
    pop ax
    ret   
    
  Trecias ENDP
  
  PrintBuf PROC
    push ax                       ; Issaugome steke registrus,
    push bx                       ; kurie keisis
    
    mov ah,40h
    mov bx,1
    int 21h                       ; int 21,40 - isvedimas i faila
                                  ; ar irengini
    pop bx                        ; Atstatome issaugotus registrus
    pop ax
    ret
  PrintBuf ENDP
  
  reg_or_mem PROC ; di rodo ten kur turi but irasytas operandas :)
    push ax
    push bx
    push cx
    push dx
    
    cmp [modas], 11b ; jeigu modas 11, tai tuomet operandas - registras :)
    jne @@toliau_modas
    
    mov bl, [rm]
    xor bh, bh
    shl bx, 2    
    cmp [W], 0
    je @@byte ; jeigu W = 0, tai tada baitas :)
    ; kitu atveju, prie bx pridedam 2 :)
    add bx, 2
    @@byte:
    push ds
    
    mov dx, es
    mov ds, dx
    mov al, [registrai+bx]
    mov [mnemonika+di], al
    inc di
    inc bx
    mov al, [registrai+bx]
    mov [mnemonika+di], al
    inc bx
    inc di
    
    pop ds
    
    jmp @@Exit
    
    @@toliau_modas:
    ; kitu atveju lieka 8 variantai su moslinkiu nuo 0 iki 2 baitu, priklausomai nuo mod :)
    ; reiktu isskirti tik atskira atveju, kai nurodomas ties.adresas (r/m = 110, mod = 00)
    cmp [rm], 110b
    jne @@toliau
    cmp [modas], 0b
    jne @@toliau
    ; turime atveji kai tiesiog. 2 baitu adr.-posl. nurodomas komandoje :)
        
    mov bx, 2 ; nes reikia spauzdint pirma vyr.baita o po to jaunesniji :)
    mov cx, 4
    
    push ds
    mov dx, es
    mov ds, dx
    
    mov [mnemonika+di], '['
    inc di
    @@ciklas:
      cmp bx, 4
      jne @@sokam2
        xor bx, bx ; spauzdinam atvirskschiai :)
      @@sokam2:
      mov al, [poslinkis+bx]
      mov [mnemonika+di], al
      inc di
      inc bx
    loop @@ciklas
    mov [mnemonika+di], ']'
    inc di
    
    pop ds
    
    jmp @@Exit
    
    @@toliau:  ; lieka tiktai visi like, t.y. stand. tik su poslinkiu nuo 0 iki 2 baitu :)
    
    cmp [rm], 011b
    jg @@virs  ; jei modas virsija 3, tai tuomet adresacija is dvieju reg. visada, kitu atv. is 1
    mov cx, 5
    mov bl, [rm]
    xor bh, bh
    shl bx, 3
    jmp @@sokam
    
    @@virs:
    mov cx, 2
    mov bx, 32 ; sokam i dvieju zenklu registrus
    mov dl, [rm]
    shl dl, 1
    add bl, dl
    xor bh, bh
    sub bx, 1000b  ; atsistojam ties tuo, kuri reiks spauzdint:)
    
    @@sokam:
    
    push ds
    mov dx, es
    mov ds, dx
    
    mov [mnemonika+di], '['
    inc di
    @@adresacija:
      mov al, [adresai+bx]
      inc bx
      mov [mnemonika+di], al
      inc di
    loop @@adresacija
    
    pop ds
    
    cmp [modas], 0
    je @@jokio_poslinkio
    
    
    ; kadangi poslinkio j.b. eina pirmiau negu vyresnysis, reikia apkeisti vietom,
    ; jei poslinkis - 2b.
    mov cl, [modas]
    xor ch, ch
    
    shl cx, 1 ; padauginam cs is dvieju, kad galetumem tinkamai atprintint poslinki :)
    
    cmp [modas], 01b
    jne @@zodis

    mov bx, 0 ; poslinkis (nuo pirmo simbolio:))

    push ds
    mov dx, es
    mov ds, dx
        
    mov [mnemonika+di], '+' ; pridedam pliusa, paskui pridesim poslinki :)
    inc di
    @@poslinkis:
      mov al, [poslinkis+bx]
      mov [mnemonika+di], al
      inc di
      inc bx
    loop @@poslinkis    
    @@jokio_poslinkio:    
    mov [adresai+di], ']'
    inc di
    
    pop ds
    
    jmp @@Exit
        
    @@zodis:
    
    mov bx, 2 ; poslinkis (nes pirma jaunesniji bita:))

    push ds
    mov dx, es
    mov ds, dx
        
    mov [mnemonika+di], '+' ; pridedam pliusa, paskui pridesim poslinki :)
    inc di
    @@poslinkis1:
      cmp bx, 4
      jne @@sokam1
        xor bx, bx ; spauzdinam atvirskschiai :)
      @@sokam1:
      mov al, [poslinkis+bx]
      mov [mnemonika+di], al
      inc di
      inc bx
    loop @@poslinkis1
    mov [mnemonika+di], ']'
    inc di
    
    pop ds
    
    @@Exit:
    pop dx
    pop cx
    pop bx
    pop ax
    ret
        
  reg_or_mem ENDP
  
  bet_op PROC
    cmp [var], 3
    jne @@sokam
      mov bx, 2
    @@sokam:
    cmp [var], 2
    je @@toliau
    cmp [var], 3
    je @@toliau
    jmp @@Exit
    @@toliau:
    lodsb
    call Sesioliktainis    
    push ds
    mov dx, es
    mov ds, dx
    mov [komanda+bx], ch
    inc bx
    mov [komanda+bx], cl
    inc bx
    pop ds
    cmp [W], 1
    jne @@Exit
    cmp [D], 0
    jne @@Exit
    lodsb
    call Sesioliktainis    
    push ds
    mov dx, es
    mov ds, dx
    mov [komanda+bx], ch
    inc bx
    mov [komanda+bx], cl
    inc bx
    pop ds 
    
    @@Exit:
    ret    
  bet_op ENDP    

END strt